package cn.wen.yinxiu.member.server.socket.handler;

import cn.wen.yinxiu.common.constant.Constant;
import cn.wen.yinxiu.common.toolkit.SocketChannelUtil;
import cn.wen.yinxiu.member.entity.UsersEntity;
import cn.wen.yinxiu.member.server.protocol.Command;
import cn.wen.yinxiu.member.server.protocol.login.LoginRequest;
import cn.wen.yinxiu.member.server.protocol.login.LoginResponse;
import cn.wen.yinxiu.member.service.UsersService;
import cn.wen.yinxiu.member.vo.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import static cn.wen.yinxiu.common.constant.Constant.TalkType.Friend;
import static cn.wen.yinxiu.common.constant.Constant.TalkType.Group;

/**
 * @ClassName: DelTalkHandler
 * @Author: 小飞
 * @Date: 2023/5/28 14:34
 * @Description: 登录请求处理类
 */
@Slf4j
@ChannelHandler.Sharable
public class LoginHandler extends SimpleChannelInboundHandler<LoginRequest> {

    private final UsersService userService;

    public LoginHandler(UsersService userService) {
        this.userService = userService;
    }


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, LoginRequest msg) throws Exception {
        log.info("登陆请求处理：{} ", JSON.toJSONString(msg));
        // 1. 登陆失败返回false
        boolean auth = userService.checkAuth(msg.getAccount(), msg.getPassword());
        Channel channel = ctx.channel();
        if (!auth) {
            // 传输消息
            channel.writeAndFlush(new LoginResponse(false));
            return;
        }
        // 查询用户信息
        UsersEntity user = userService.queryUserInfoByAccount(msg.getAccount());
        // 2. 登陆成功绑定Channel
        // 2.1 绑定用户ID
        SocketChannelUtil.addChannel(user.getId(), channel);
        // 2.2 绑定群组
        List<Long> groupsIdList = userService.queryUserGroupsIdList(user.getId());
        for (Long groupId : groupsIdList) {
            SocketChannelUtil.addChannelGroup(groupId, channel);
        }
        // 3. 反馈消息；用户信息、用户对话框列表、好友列表、群组列表
        // 组装消息包
        LoginResponse loginResponse = new LoginResponse();
        // 3.1 用户信息
        UserInfo userInfo = userService.queryUserInfo(user.getId());
        // 3.2 对话框
        List<TalkBoxInfo> talkBoxInfoList = userService.queryTalkBoxInfoList(user.getId());
        for (TalkBoxInfo talkBoxInfo : talkBoxInfoList) {
            ChatTalkDto chatTalk = new ChatTalkDto();
            chatTalk.setTalkId(talkBoxInfo.getTalkId());
            chatTalk.setTalkType(talkBoxInfo.getTalkType());
            chatTalk.setTalkName(talkBoxInfo.getTalkName());
            chatTalk.setTalkAvatar(talkBoxInfo.getTalkAvatar());
            chatTalk.setTalkSketch(talkBoxInfo.getTalkSketch());
            chatTalk.setTalkTime(talkBoxInfo.getTalkTime());
            loginResponse.getChatTalkList().add(chatTalk);

            // 好友；聊天消息
            if (Friend.getCode().equals(talkBoxInfo.getTalkType())) {
                List<ChatRecordVO> chatRecordDtoList = new ArrayList<>();
                List<ChatRecordInfo> chatRecordInfoList = userService.queryChatRecordInfoList(talkBoxInfo.getTalkId(),
                        user.getId(), talkBoxInfo.getTalkType(), Constant.NUM_ONE);
                for (ChatRecordInfo chatRecordInfo : chatRecordInfoList) {
                    ChatRecordVO chatRecordVO = new ChatRecordVO();
                    chatRecordVO.setTalkId(talkBoxInfo.getTalkId());
                    boolean msgType = user.getId() == chatRecordInfo.getUserId();
                    // 自己发的消息
                    if (msgType) {
                        chatRecordVO.setUserId(chatRecordInfo.getUserId());
                        chatRecordVO.setMsgUserType(0); // 消息类型[0自己/1好友]
                    }
                    // 好友发的消息
                    else {
                        chatRecordVO.setUserId(chatRecordInfo.getFriendId());
                        chatRecordVO.setMsgUserType(1); // 消息类型[0自己/1好友]
                    }
                    chatRecordVO.setMsgContent(chatRecordInfo.getMsgContent());
                    chatRecordVO.setMsgType(chatRecordInfo.getMsgType());
                    chatRecordVO.setMsgTime(chatRecordInfo.getTalkTime());
                    chatRecordDtoList.add(chatRecordVO);
                }
                chatTalk.setChatRecordList(chatRecordDtoList);
            }
            // 群组；聊天消息
            else if (Group.getCode().equals(talkBoxInfo.getTalkType())) {
                List<ChatRecordVO> chatRecordDtoList = new ArrayList<>();
                List<ChatRecordInfo> chatRecordInfoList = userService.queryChatRecordInfoList(
                        talkBoxInfo.getTalkId(), user.getId(), talkBoxInfo.getTalkType(), Constant.NUM_ONE);
                for (ChatRecordInfo chatRecordInfo : chatRecordInfoList) {
                    UserInfo memberInfo = userService.queryUserInfo(chatRecordInfo.getUserId());
                    ChatRecordVO ChatRecordVO = new ChatRecordVO();
                    ChatRecordVO.setTalkId(talkBoxInfo.getTalkId());
                    ChatRecordVO.setUserId(memberInfo.getUserId());
                    ChatRecordVO.setUserNickName(memberInfo.getNickname());
                    ChatRecordVO.setUserAvatar(memberInfo.getUserAvatar());
                    ChatRecordVO.setMsgContent(chatRecordInfo.getMsgContent());
                    ChatRecordVO.setMsgTime(chatRecordInfo.getTalkTime());
                    boolean msgType = user.getId() == chatRecordInfo.getUserId();
                    ChatRecordVO.setMsgUserType(msgType ? 0 : 1); // 消息类型[0自己/1好友]
                    ChatRecordVO.setMsgType(chatRecordInfo.getMsgType());
                    chatRecordDtoList.add(ChatRecordVO);
                }
                chatTalk.setChatRecordList(chatRecordDtoList);
            }

        }
        // 3.3 群组
        List<GroupInfo> groupsInfoList = userService.queryUserGroupInfoList(user.getId());
        loginResponse.getGroupsList().addAll(groupsInfoList);
        // 3.4 好友
        List<UserFriendInfo> userFriendInfoList = userService.queryUserFriendInfoList(user.getId(), Constant.NUM_ONE);
        loginResponse.getUserFriendList().addAll(userFriendInfoList);
        loginResponse.setSuccess(true);
        loginResponse.setUserId(userInfo.getUserId());
        loginResponse.setUserNickName(userInfo.getNickname());
        loginResponse.setUserAvatar(userInfo.getUserAvatar());
        // 4.将封装好的LoginResponse生成Web请求返回
        ByteBuf byteBuf = getByteBuf(ctx, user.getId(), loginResponse);
        // 传输消息
        channel.writeAndFlush(new TextWebSocketFrame(byteBuf));
    }

    public ByteBuf getByteBuf(ChannelHandlerContext ctx, Long userId, LoginResponse loginResponse) {
        ByteBuf bytebuf = ctx.alloc().buffer();
        JSONObject data = new JSONObject();
        data.put("type", Command.LoginResponse);
        data.put("code", 200);
        JSONObject params = new JSONObject();
        params.put("userId", userId);
        params.put("talkInfo", loginResponse);
        data.put("data", params);
        log.info("登录成功后的返回数据：{}", data);
        byte []bytes = data.toJSONString().getBytes(Charset.forName("utf-8"));
        bytebuf.writeBytes(bytes);
        return bytebuf;
    }
}
